﻿package cocoaas3{

	import jp.progression.casts.*;
	import jp.progression.commands.display.*;
	import jp.progression.commands.lists.*;
	import jp.progression.commands.managers.*;
	import jp.progression.commands.media.*;
	import jp.progression.commands.net.*;
	import jp.progression.commands.tweens.*;
	import jp.progression.commands.*;
	import jp.progression.data.*;
	import jp.progression.events.*;
	import jp.progression.loader.*;
	import jp.progression.*;
	import jp.progression.scenes.*;
	import caurina.transitions.Tweener;
	import jp.nium.core.debug.Logger;

	import flash.events.*;
	import flash.display.*;

	import cocoaas3.flash.*;

	public class UIViewController extends SceneObject{

		//
		//-------------------------------------------------------------------------------------------
		// original variables
		//-------------------------------------------------------------------------------------------
		//
		private var _view:UIView = new UIView();
		internal var _navigationController:UINavigationController;
		internal var _tabBarController:UITabBarController;
		internal var _presentingViewController:UIViewController;
		private var _presentedViewController:UIViewController;

		public function get view():UIView{
			return _view;
		}
		public function set view( val:UIView ):void{
			_view = val;
		}

		// The navigation item used to represent the view controller in a parent's navigation bar. (read-only)
		private var _navigationItem:UINavigationItem;
		public function get navigationItem():UINavigationItem{
			return _navigationItem;
		}

		// The nearest ancestor in the view controller hierarchy that is a navigation controller. (read-only)
		// 一番近い親 navigationController を返す
		public function get navigationController():UINavigationController{
			return _navigationController;
		}

		// The nearest ancestor in the view controller hierarchy that is a tab bar controller. (read-only)
		// 一番近い親 tabBarController を返す
		public function get tabBarController():UITabBarController{
			if( _tabBarController ){
				return _tabBarController;
			} else if( navigationController ){
				return navigationController.tabBarController;
			} else if( presentingViewController ){
				return presentingViewController.tabBarController;
			}
			return null;
		}

		// The tab bar item that represents the view controller when added to a tab bar controller.
		public var tabBarItem:UITabBarItem;


		// The view controller that is presented by this view controller, or one of its ancestors in the view controller hierarchy. (read-only)
		// この VC が表示しているモーダルVC
		public function get presentedViewController():UIViewController{
			return _presentedViewController;
		}

		// The view controller that presented this view controller. (read-only)
		// このモーダル VC を表示しているVC
		// 直接表示されていなくても、あるVCを経由して表示されている場合は、それを表示しているVCを返す
		public function get presentingViewController():UIViewController{
			return _presentingViewController;
		}

		//
		//-------------------------------------------------------------------------------------------
		// custom variables
		//-------------------------------------------------------------------------------------------
		//
		public var animated:Boolean = true;
		internal var customContentContainer:Sprite = new Sprite();


		//
		//-------------------------------------------------------------------------------------------
		// original functions
		//-------------------------------------------------------------------------------------------
		//
		public function UIViewController( title:String="vc" ){
			super( title );
			_navigationItem = new UINavigationItem( title );
			view.addChild( customContentContainer );
		}


		/**
		 * シーン移動時に目的地がシーンオブジェクト自身もしくは子階層だった場合に、階層が変更された直後に送出されます。
		 * このイベント処理の実行中には、ExecutorObject を使用した非同期処理が行えます。
		 */
		override protected function atSceneLoad():void {
		}

		/**
		 * シーンオブジェクト自身が目的地だった場合に、到達した瞬間に送出されます。
		 * このイベント処理の実行中には、ExecutorObject を使用した非同期処理が行えます。
		 */
		override protected function atSceneInit():void {
			if( navigationController ){
				navigationController.customContentContainer.addChild( view );
			} else if( presentingViewController ){
				stage.addChild( view );
			} else if( tabBarController ){
				tabBarController.customContentContainer.addChild( view );
			} else {
				container.addChild( view );
			}
		}

		/**
		 * シーンオブジェクト自身が出発地だった場合に、移動を開始した瞬間に送出されます。
		 * このイベント処理の実行中には、ExecutorObject を使用した非同期処理が行えます。
		 */
		override protected function atSceneGoto():void {
		}

		/**
		 * シーン移動時に目的地がシーンオブジェクト自身もしくは親階層だった場合に、階層が変更される直前に送出されます。
		 * このイベント処理の実行中には、ExecutorObject を使用した非同期処理が行えます。
		 */
		override protected function atSceneUnload():void {
			// navigationController 内なら、viewの削除は navigationController にまかせる
			// ほかのVCによってpresentされているなら、親のVCにまかせる
			if( navigationController || presentingViewController ){
				return;
			}
			if( view.parent ){
				view.parent.removeChild( view );
			}
		}







		// Presents a view controller.
		// モーダルビュー表示
		public function presentViewController( viewController:UIViewController, animated:Boolean=true, completion:Function=null ):void{
			Logger.info( this, "presentViewController vc="+ viewController );
			this._presentedViewController = viewController;
			viewController._presentingViewController = this;
			addScene( viewController );
			manager.goto( viewController.sceneId );

			//viewController.view.alpha = 0.5;

			// 遷移描画
			var slist = new SerialList();
			if( animated ){
				stage.mouseChildren = false;
				viewController.view.y = stage.stageHeight;
				slist.addCommand(
					new DoTweener( viewController.view, {y:0, time:0.33, transition:"easeOutSine"} ),
				null);
			}
			if( this.view.parent ){
				slist.addCommand(
					new RemoveChild( this.view.parent, this.view ),
					function(){ stage.mouseChildren = true; },
				null);
			}
			slist.addCommand(
			    viewController.viewDidAppear,
			null);
			slist.execute();

		}

		// Dismisses the view controller that was presented by the receiver.
		// モーダルビュー閉じる
		// If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.
		// もしthisが他のVCによって表示されたものなら、その表示しているVCにフォワードします。
		public function dismissViewController( animated:Boolean=true, completion:Function=null ):void{
			Logger.info( this, "dismissViewController" );
			if( this.presentingViewController ){
				Logger.info( this, "dismissViewController 自身を表示しているVCに転送します。" );
				this.presentingViewController.dismissViewController( animated, completion );
				return;
			}

			if( !this.presentedViewController ){
				Logger.warn( this, "dismissViewController presentedViewControllerがありません。" );
				return;
			}

			// 遷移描画
			var slist = new SerialList();
			if( animated ){
				stage.mouseChildren = false;
				slist.addCommand(
					new DoTweener( this.presentedViewController.view, {y:stage.stageHeight, time:0.33, transition:"easeInSine"} ),
				null);
			}
			slist.addCommand(
				new RemoveChild( this.presentedViewController.view.parent, this.presentedViewController.view ),
				function(){ stage.mouseChildren = true; },
				completion,
			null);
			slist.execute();

			this._presentedViewController = null;
			manager.goto( this.sceneId );
		}

		// Creates the view that the controller manages.
		public function loadView():void{
		}

		// ビューが最後まで描画された後やアニメーションが終了した後にこの処理が呼ばれる。
		public function viewDidAppear():void{}

		//
		//
		// custom
		//
		//


		//override public function get stage():Stage{
		//	return view.stage;
		//}

	}
}